﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using TripLOAMobile.WS_SoapTrip;
using TripLOAMobile.InternalEntities;
using TripLOAMobile.InternalEntities.ExtensionsMethods;
using CompactFramework.Utilities.Localization;

namespace TripLOAMobile
{
    public delegate void Dispose();
    public partial class SearchTravel : LocalizedForm
    {
        private AnimationControl animation;
        public Dispose DelegateDispose;
        private bool gpsDepEvent = false;
        private bool gpsDestEvent = false;
        private bool first = false;
        private object controlSender;

        //private InsertTravelInfo formStatus;
        private SearchCriteria formStatus;

        /*
        #region MapPanel declarations
        private Panel panel;
        private GMMControl.GMMControl map;
        private Button exitButton;
        #endregion
        */

        private string searchStatus;

        public string SearchStatus
        {
            get
            {
                return searchStatus;
            }
        }

        public int MaxNumberOfResults
        {
            get;
            set;
        }

        internal TripInfo[] ListOfResults
        {
            get
            {
                return listOfResults;
            }
        }

        private TripInfo[] listOfResults;

        public SearchTravel(int maxNumberOfResults)
        {
            InitializeComponent();
            delta = lblDest.Top - lblDpt.Top;
            MaxNumberOfResults = maxNumberOfResults;
            this.AddMenusToDictionary();
            UpdateResources();
            controlSender = null;
            formStatus = new SearchCriteria();
            DelegateDispose = new Dispose(this.Dispose);
            #region creation of the control for the animation
            animation = new AnimationControl();
            //if you want to use some other bitmaps...
            //animation = new AnimationControl(130,TripLOAMobile.Properties.Resources.circle001, TripLOAMobile.Properties.Resources.circle002, TripLOAMobile.Properties.Resources.circle003, TripLOAMobile.Properties.Resources.circle004, TripLOAMobile.Properties.Resources.circle005, TripLOAMobile.Properties.Resources.circle006, TripLOAMobile.Properties.Resources.circle007, TripLOAMobile.Properties.Resources.circle008, TripLOAMobile.Properties.Resources.circle009, TripLOAMobile.Properties.Resources.circle010, TripLOAMobile.Properties.Resources.circle011, TripLOAMobile.Properties.Resources.circle012);
            int x = this.Width / 2 - animation.Width / 2;
            int y = this.Height / 2 - animation.Height / 2;
            animation.Location = new Point(x, y);
            this.Controls.Add(animation);
            animation.BringToFront();
            #endregion
        }

        protected override void AddMenusToDictionary()
        {
            this.AddMenuToDictionary(this.menuLeft, "menuLeft");
            this.AddMenuToDictionary(this.menuRight, "menuRight");
        }

        //search
        private void menuItem2_Click(object sender, EventArgs e)
        {
            formStatus.FromTime = ((this.chkFromDtTm.Checked)) ? fromDtTm.Value : DateTime.Now;
            formStatus.ToTime = ((this.chkToDtTm.Checked)) ? toDtTm.Value : DateTime.MaxValue;

            if (CheckTexture.CheckSearchTravel(txtBoxDepAddress, txtBoxDesAddress))
            {
                this.startAnimation();
                Welcome.rrp.SendSearchRequest(this, rrp_SearchResponse, formStatus);
            }
        }

        #region ResponseHandling
        void rrp_SearchResponse(RemoteResourceProvider.TripListResponseEventArgs e)
        {
            this.stopAnimation();
            listOfResults = e.Results;
            searchStatus = e.Status;
            if ((e.Status == RemoteResourceProvider.okStatus) && (e.Results != null))
            {
                if (listOfResults.Length == 0)
                    MessageBox.Show(ResourceManager.Instance.GetString("EmptyElementList"));
                else
                {
                    ShowSearchResults ssr = new ShowSearchResults(listOfResults, searchStatus);
                    Welcome.formBuffer.Add(ssr, "ShowSearchResults");
                    ssr.ShowDialog();
                    ssr.Dispose(); //[Andrea Russino]
                }
            }
            else
            {
                MessageBox.Show(e.Status);
            }
        }
        #endregion

        #region start/stop animation
        //delegate void startAnimationDel();
        delegate void animationDel();
        private void stopAnimation()
        {
            foreach (Control c in this.Controls)
            {
                c.Enabled = true;
            }
            this.menuLeft.Enabled = true;
            this.menuRight.Enabled = true;
            this.animation.StopAnimation();
        }
        private void startAnimation()
        {
            foreach (Control c in this.Controls)
            {
                c.Enabled = false;
            }
            this.menuLeft.Enabled = false;
            this.menuRight.Enabled = false;
            this.animation.StartAnimation();
        }

        #endregion


        private void menuItem1_Click(object sender, EventArgs e)
        {
            Welcome.formBuffer.Close();
        }

        #region View
        protected override void OnPaint(PaintEventArgs e)
        {
            using (Graphics g = e.Graphics)
            {
                //Title decoration
                Point[] p = new Point[]{
                    new Point(40,25), 
                    new Point(195,25), 
                    new Point(190,30), 
                    new Point(40,30)};
                using(Brush b = new SolidBrush(Color.Green))
                    g.FillPolygon(b, p);

                p[0].Y = p[1].Y = 30;
                p[2].Y = p[3].Y = 35;
                p[1].X -= 10;
                p[2].X -= 10;
                using (Brush b = new SolidBrush(Color.GreenYellow))
                    g.FillPolygon(b, p);

                g.DrawImage(Properties.Resources.circles, 8, 5);

                //Departure Decoration
                DecorateGroup(g, txtBoxDepAddress,btnDepGPS,btnDepMap,3,10);

                //Destination Decoration
                DecorateGroup(g, txtBoxDesAddress, btnDestGPS, btnDestMap, 3, 10);
            }

            //Added to prevent painting of "ok" button
            WinAPI.ShowDoneButton(this.Handle, false);
            base.OnPaint(e);
        }

        private void DecorateGroup(Graphics g, TextBox txtbox, Button upperButton, Button lowerButton, int offset,int roundDiameter)
        {
            using (Brush b = new SolidBrush(Color.FromArgb(222, 241, 126)))
            {
                int left = txtbox.Left - 2*offset;
                int right = upperButton.Right + 2*offset;
                int top = upperButton.Top - 2*offset;
                int bottom = lowerButton.Bottom + 2*offset;
                //int roundDiameter = 10;

                Rectangle r = new Rectangle(left, top, roundDiameter, roundDiameter);
                g.FillEllipse(b, r);
                r.X = right - roundDiameter - 1;
                g.FillEllipse(b, r);
                r.Y = bottom - roundDiameter - 1;
                g.FillEllipse(b, r);
                r.X = left;
                g.FillEllipse(b, r);
                r.X = left + roundDiameter / 2; r.Y = top; r.Width = right - left - roundDiameter; r.Height = bottom - top;
                g.FillRectangle(b, r);
                r.X = left; r.Y = top + roundDiameter / 2; r.Width = roundDiameter / 2; r.Height = bottom - top - roundDiameter;
                g.FillRectangle(b, r);
                r.X = right - roundDiameter / 2;
                g.FillRectangle(b, r);
            }
            using (Brush b = new SolidBrush(Color.FromArgb(48, 138, 13)))
            {
                g.FillRectangle(b, txtbox.Left - offset, txtbox.Top - offset, upperButton.Left - txtbox.Left + offset, txtbox.Height + 2*offset);
                g.FillRectangle(b, upperButton.Left - offset, upperButton.Top - offset, upperButton.Width + 2*offset, lowerButton.Bottom - upperButton.Top + 2*offset);//190, 53, 40, 55);
            }
        }
        #endregion

        private void _Closed(object sender, System.EventArgs e)
        {
            if (gpsDepEvent)
            {
                Welcome.gps.DeviceStateChanged -= gps_DepDeviceStateChanged;
                Welcome.gps.LocationChanged -= gps_DepLocationChanged;
                gpsDepEvent = false;
            }
            if (gpsDestEvent)
            {
                Welcome.gps.DeviceStateChanged -= gps_DestDeviceStateChanged;
                Welcome.gps.LocationChanged -= gps_DestLocationChanged;
            }
        }

        private void checkFromDtTm_CheckStateChanged(object sender, EventArgs e)
        {
            fromDtTm.Enabled = chkFromDtTm.Checked ? true : false;

            /*if (chkFromDtTm.Checked)
                chkFromDtTm.Text = "modify Date";*/
        }

        private void checkToDtTm_CheckStateChanged(object sender, EventArgs e)
        {
            toDtTm.Enabled = chkToDtTm.Checked ? true : false;

            /*if (chkToDtTm.Checked)
                chkToDtTm.Text = "modify Date";*/
        }

        private void txtBoxDepAddress_GotFocus(object sender, EventArgs e)
        {
            controlSender = sender;
            city.Text = formStatus.DepartureFields.City;
            province.Text = formStatus.DepartureFields.Province;
            zipcode.Text = formStatus.DepartureFields.ZipCode;
            nation.Text = formStatus.DepartureFields.State;
            street.Text = formStatus.DepartureFields.Street;
            insertAddress.Visible = true;
            WinAPI.SetFocus(street.Handle);
        }

        private void txtBoxDesAddress_GotFocus(object sender, EventArgs e)
        {
            controlSender = sender;
            city.Text = formStatus.DestinationFields.City;
            province.Text = formStatus.DestinationFields.Province;
            zipcode.Text = formStatus.DestinationFields.ZipCode;
            nation.Text = formStatus.DestinationFields.State;
            street.Text = formStatus.DestinationFields.Street;
            insertAddress.Visible = true;
            WinAPI.SetFocus(street.Handle);
        }

        #region Map Handlers
        private void btnDepMap_Click(object sender, EventArgs e)
        {
            MapSelection map;
            if (this.txtBoxDepAddress.Text.Equals("")) map = new MapSelection();
            else
            {
                String[] temp = this.txtBoxDepAddress.Text.Split(',');
                try
                {
                    map = new MapSelection(Convert.ToDouble(temp[0]), Convert.ToDouble(temp[1]));
                }
                catch (Exception)//(FormatException) //FormatException rileva solo errore se stringa invece di double, ma non IndexOutOfRange se non ci sono virgole
                {
                    map = new MapSelection();
                }
            }
            Welcome.formBuffer.Add(map, ResourceManager.Instance.GetString("MapSelection"));
            map.ShowDialog();
            
            if (map.AddressAcquired)
            {
                formStatus.setDepLatLong(map.Latitude, map.Longitude);

                menuRight.Enabled = false;

                Welcome.rrp.SendReverseGeoCodingRequest(
                    this,
                    rrp_DepGeocodeResponse,
                    new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = formStatus.LatDep, Lng = formStatus.LongDep });
            }
            
            map.Dispose();
            /*
            panel = CreateMapPanel(true);
            this.Controls.Add(panel);
            this.Controls.SetChildIndex(panel, 0);
            */
        }

        private void btnDestMap_Click(object sender, EventArgs e)
        {
            MapSelection map;
            if (this.txtBoxDesAddress.Text.Equals("")) map = new MapSelection();
            else
            {
                String[] temp = this.txtBoxDesAddress.Text.Split(',');
                try
                {
                    map = new MapSelection(Convert.ToDouble(temp[0]), Convert.ToDouble(temp[1]));
                }
                catch (FormatException)
                {
                    map = new MapSelection();
                }
            }
            Welcome.formBuffer.Add(map, ResourceManager.Instance.GetString("MapSelection"));
            map.ShowDialog();
            
            if (map.AddressAcquired)
            {
                formStatus.setDesLatLong(map.Latitude, map.Longitude);

                menuRight.Enabled = false;

                Welcome.rrp.SendReverseGeoCodingRequest(
                    this,
                    rrp_DestGeocodeResponse,
                    new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = formStatus.LatDes, Lng = formStatus.LongDes });
            }
 
            map.Dispose();
            /*
            panel = CreateMapPanel(false);
            this.Controls.Add(panel);
            this.Controls.SetChildIndex(panel, 0);
            */
        }
        /*
        private Panel CreateMapPanel(bool isDep)
        {
            Panel mapPanel = new Panel();
            mapPanel.Size = new Size(213, 152);
            mapPanel.BackColor = Color.FromArgb(48, 138, 13);
            mapPanel.Location = new Point((this.ClientSize.Width-213)/2,(this.ClientSize.Height-152)/2);
            map = new GMMControl.GMMControl();
            map.BorderStyle = BorderStyle.FixedSingle;
            map.Location = new Point(1, 1);
            map.Size = new Size(211, 150);
            map.TabIndex = 0;
            if (isDep)
            {
                if (this.txtBoxDepAddress.Text.Equals("")) map.LoadMap();
                else
                {
                    String[] temp = this.txtBoxDepAddress.Text.Split(',');
                    map.LoadMap(Convert.ToDouble(temp[0]), Convert.ToDouble(temp[1]));
                }
                map.SelectedLocationChanged += new EventHandler(map_DepSelectedLocationChanged);
            }
            else
            {
                if (this.txtBoxDesAddress.Text.Equals("")) map.LoadMap();
                else
                {
                    String[] temp = this.txtBoxDesAddress.Text.Split(',');
                    map.LoadMap(Convert.ToDouble(temp[0]), Convert.ToDouble(temp[1]));
                }
                map.SelectedLocationChanged += new EventHandler(map_DestSelectedLocationChanged);
            }
            exitButton = new Button();
            exitButton.Text = "Exit";
            exitButton.Size = new Size(50, 15);
            exitButton.Location = new Point(5, 130);
            exitButton.BackColor = Color.White;
            exitButton.Click += new EventHandler(exitButton_Click);
            map.Controls.Add(exitButton);
            mapPanel.Controls.Add(map);
            return mapPanel;
        }

        private void map_DepSelectedLocationChanged(object sender, System.EventArgs e)
        {
            GMMGetTiles.GeoCoordinate coords = map.SelectedLocation;
            txtBoxDepAddress.Text = coords.lat.ToString() + "," + coords.lon.ToString();
        }

        private void map_DestSelectedLocationChanged(object sender, System.EventArgs e)
        {
            GMMGetTiles.GeoCoordinate coords = map.SelectedLocation;
            txtBoxDesAddress.Text = coords.lat.ToString() + "," + coords.lon.ToString();
        }

        private void exitButton_Click(object sender, System.EventArgs e)
        {   
            panel.Dispose();
        }
        */
        #endregion;

        #region GPS Event Handlers

        delegate void updatePosition();

        public void gps_DepLocationChanged(object sender, GPS.LocationChangedEventArgs args)
        {
            Welcome.gps.Position = args.Position;
            if (first)
            {
                first = false;
                MessageBox.Show(ResourceManager.Instance.GetString("gpsAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                updatePosition p = new updatePosition(updateDepPosition);
                this.Invoke(p);
            }
        }

        public void gps_DepDeviceStateChanged(object sender, GPS.DeviceStateChangedEventArgs args)
        {
            Welcome.gps.DeviceState = args.DeviceState;
            if (first)
            {
                first = false;
                DialogResult result = MessageBox.Show(ResourceManager.Instance.GetString("gpsAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                updatePosition p = new updatePosition(updateDepPosition);
                this.Invoke(p);
            }
        }

        public void gps_DestLocationChanged(object sender, GPS.LocationChangedEventArgs args)
        {
            Welcome.gps.Position = args.Position;
            if (first)
            {
                first = false;
                DialogResult result = MessageBox.Show(ResourceManager.Instance.GetString("gpsAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                updatePosition p = new updatePosition(updateDestPosition);
                this.Invoke(p);
            }
        }

        public void gps_DestDeviceStateChanged(object sender, GPS.DeviceStateChangedEventArgs args)
        {
            Welcome.gps.DeviceState = args.DeviceState;
            if (first)
            {
                first = false;
                MessageBox.Show(ResourceManager.Instance.GetString("gpsAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                updatePosition p = new updatePosition(updateDestPosition);
                this.Invoke(p);
            }
        }

        private void updateDepPosition()
        {
            formStatus.setDepLatLong(Welcome.gps.Position.Latitude, Welcome.gps.Position.Longitude);

            menuRight.Enabled = false;

            Welcome.rrp.SendReverseGeoCodingRequest(
                this,
                rrp_DepGeocodeResponse,
                new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = Welcome.gps.Position.Latitude, Lng = Welcome.gps.Position.Longitude });
        }

        private void updateDestPosition()
        {
            formStatus.setDesLatLong(Welcome.gps.Position.Latitude, Welcome.gps.Position.Longitude);

            menuRight.Enabled = false;

            Welcome.rrp.SendReverseGeoCodingRequest(
                this,
                rrp_DestGeocodeResponse,
                new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = Welcome.gps.Position.Latitude, Lng = Welcome.gps.Position.Longitude });
        }
        #endregion

        #region GPS Handlers
        private void btnDepGPS_Click(object sender, EventArgs e)
        {
            if (!Welcome.gps.Opened)
            {
                DialogResult result = MessageBox.Show(ResourceManager.Instance.GetString("wantGpsOn"), 
                                                      ResourceManager.Instance.GetString("gpsCaption"), 
                                                      MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    Welcome.gps.Open();
                    gpsDepEvent = true;
                    first = true;
                    Welcome.gps.DeviceStateChanged += new GPS.Gps.DeviceStateChangedEventHandler(gps_DepDeviceStateChanged);
                    Welcome.gps.LocationChanged += new GPS.Gps.LocationChangedEventHandler(gps_DepLocationChanged);
                }
            }
            else
            {
                try
                {
                    if (Welcome.gps.Position.LatitudeValid && Welcome.gps.Position.LongitudeValid)
                    {
                        formStatus.setDepLatLong(Welcome.gps.Position.Latitude, Welcome.gps.Position.Longitude);

                        menuRight.Enabled = false;

                        Welcome.rrp.SendReverseGeoCodingRequest(
                            this,
                            rrp_DepGeocodeResponse,
                            new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = Welcome.gps.Position.Latitude, Lng = Welcome.gps.Position.Longitude });
                    }
                    else
                    {
                        MessageBox.Show(ResourceManager.Instance.GetString("gpsNotAvailable"),
                                    ResourceManager.Instance.GetString("gpsCaption"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
                    }
                }
                catch (NullReferenceException)
                {
                    MessageBox.Show(ResourceManager.Instance.GetString("gpsNotAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
                }
            }
        }

        private void btnDestGPS_Click(object sender, EventArgs e)
        {
            if (!Welcome.gps.Opened)
            {
                DialogResult result = MessageBox.Show(ResourceManager.Instance.GetString("wantGpsOn"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    Welcome.gps.Open();
                    gpsDestEvent = true;
                    first = true;
                    Welcome.gps.DeviceStateChanged += new GPS.Gps.DeviceStateChangedEventHandler(gps_DestDeviceStateChanged);
                    Welcome.gps.LocationChanged += new GPS.Gps.LocationChangedEventHandler(gps_DestLocationChanged);
                }
            }
            else
            {
                try
                {
                    if (Welcome.gps.Position.LatitudeValid && Welcome.gps.Position.LongitudeValid)
                    {
                        formStatus.setDesLatLong(Welcome.gps.Position.Latitude, Welcome.gps.Position.Longitude);

                        menuRight.Enabled = false;

                        Welcome.rrp.SendReverseGeoCodingRequest(
                            this,
                            rrp_DestGeocodeResponse,
                            new TripLOAMobile.WS_GeoRef.GeoPoint() { Lat = Welcome.gps.Position.Latitude, Lng = Welcome.gps.Position.Longitude });
                    }
                    else
                    {
                        MessageBox.Show(ResourceManager.Instance.GetString("gpsNotAvailable"),
                                    ResourceManager.Instance.GetString("gpsCaption"),
                                    MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
                    }
                }
                catch (NullReferenceException)
                {
                    MessageBox.Show(ResourceManager.Instance.GetString("gpsNotAvailable"),
                                ResourceManager.Instance.GetString("gpsCaption"),
                                MessageBoxButtons.OK, MessageBoxIcon.Asterisk, MessageBoxDefaultButton.Button2);
                }
            }
        }
        #endregion;

        #region GeoCodeResponseHandling
        void rrp_DepGeocodeResponse(RemoteResourceProvider.GeoCodeResponseEventArgs e)
        {
            if (e.Status == RemoteResourceProvider.okStatus)
            {
                formStatus.DepartureFields.City = e.Address.getCityRGeoCoded();
                formStatus.DepartureFields.Province = e.Address.getProvinceRGeoCoded();
                formStatus.DepartureFields.ZipCode = e.Address.getZipCodeRGeoCoded();
                formStatus.DepartureFields.State = e.Address.getStateRGeoCoded();
                formStatus.DepartureFields.Street = e.Address.getStreetRGeoCoded();
                txtBoxDepAddress.Text = formStatus.DepartureFields.getReadableString();
            }
            else MessageBox.Show(e.Status);

            menuRight.Enabled = true;
        }

        void rrp_DestGeocodeResponse(RemoteResourceProvider.GeoCodeResponseEventArgs e)
        {
            if (e.Status == RemoteResourceProvider.okStatus)
            {
                formStatus.DestinationFields.City = e.Address.getCityRGeoCoded();
                formStatus.DestinationFields.Province = e.Address.getProvinceRGeoCoded();
                formStatus.DestinationFields.ZipCode = e.Address.getZipCodeRGeoCoded();
                formStatus.DestinationFields.State = e.Address.getStateRGeoCoded();
                formStatus.DestinationFields.Street = e.Address.getStreetRGeoCoded();
                txtBoxDesAddress.Text = formStatus.DestinationFields.getReadableString();
            }
            else MessageBox.Show(e.Status);

            menuRight.Enabled = true;
        }
        #endregion

        #region PanelButtons
        private void btnCancel_Click(object sender, EventArgs e)
        {
            foreach (Control txtBox in insertAddress.Controls)
                if (txtBox is TextBox)
                    txtBox.Text = "";
            insertAddress.Visible = false;
            resetTabIndex((TextBox)controlSender);
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            bool addressModified = false, dep=true;
            AddressFields actualFields;
            TextBox control = (TextBox)controlSender;
            if (control.Name == "txtBoxDepAddress")
                actualFields = formStatus.DepartureFields;
            else
            {
                actualFields = formStatus.DestinationFields;
                dep = false;
            }

            if (actualFields.City != city.Text)
            {
                actualFields.City = city.Text;
                addressModified = true;
            }
            if (actualFields.State != nation.Text)
            {
                actualFields.State = nation.Text;
                addressModified = true;
            }
            if (actualFields.Street != street.Text)
            {
                actualFields.Street = street.Text;
                addressModified = true;
            }
            if (actualFields.Province != province.Text)
            {
                actualFields.Province = province.Text;
                addressModified = true;
            }
            if (actualFields.ZipCode != zipcode.Text)
            {
                actualFields.ZipCode = zipcode.Text;
                addressModified = true;
            }
            if (addressModified)
            {
                control.Text = actualFields.getReadableString();//nation.Text + "," + city.Text + "," + province.Text + "," + street.Text;
                if (dep)
                    formStatus.setDepLatLongNOTDefined();
                else
                    formStatus.setDesLatLongNOTDefined();
            }
            insertAddress.Visible = false;
            resetTabIndex((TextBox)controlSender);
        }

        /// <summary>
        /// Set the focus to the next control, with respect to the fill status of a specified control
        /// [Andrea Russino]
        /// </summary>
        /// <param name="field">Filling control</param>
        private void resetTabIndex(TextBox field)
        {
            if (field == txtBoxDepAddress)
                if (field.Text.Length == 0)
                    WinAPI.SetFocus(btnDepGPS.Handle);
                else
                    WinAPI.SetFocus(btnDestGPS.Handle);
            else
                if (field.Text.Length == 0)
                    WinAPI.SetFocus(btnDestGPS.Handle);
                else
                    WinAPI.SetFocus(fromDtTm.Handle);
        }

        void insertAddress_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
        {
            using (Graphics g = e.Graphics)
                using (Pen p = new Pen(Color.GreenYellow, 4))
                {
                    Rectangle r = new Rectangle(2, 2, insertAddress.Width - 4, insertAddress.Height - 4);
                    g.DrawRectangle(p, r);
                }
        }

        private void _Click(object sender, System.EventArgs e)
        {
            insertAddress.Visible = false;
        }
        #endregion

        #region SIP handling
        private object focused; //Which editable control was last focused
        private int delta; //variation from the original location due to keyboard visualization

        private void editableControl_GotFocus(object sender, EventArgs e)
        {
            //Shows the INPUT_PANEL
            focused = sender;
            if(sender != fromDtTm && sender != toDtTm) sip.Enabled = true;
        }

        private void editableControl_LostFocus(object sender, EventArgs e)
        {
            //Hides the INPUT_PANEL
            sip.Enabled = false;
        }

        private void sip_EnabledChanged(object sender, EventArgs e)
        {
            if (focused == fromDtTm || focused == toDtTm)
            {
                if (sip.Enabled)
                {
                    lblDest.Top = lblDpt.Top;
                    txtBoxDesAddress.Top = txtBoxDepAddress.Top;
                    btnDestGPS.Top = btnDepGPS.Top;
                    btnDestMap.Top = btnDepMap.Top;

                    lblFromDtTm.Top -= delta;
                    fromDtTm.Top -= delta;
                    chkFromDtTm.Top -= delta;
                    lblToDtTm.Top -= delta;
                    toDtTm.Top -= delta;
                    chkToDtTm.Top -= delta;
                }
                else
                {
                    lblDest.Top += delta;
                    txtBoxDesAddress.Top += delta;
                    btnDestGPS.Top += delta;
                    btnDestMap.Top += delta;

                    lblFromDtTm.Top += delta;
                    fromDtTm.Top += delta;
                    chkFromDtTm.Top += delta; 
                    lblToDtTm.Top += delta;
                    toDtTm.Top += delta;
                    chkToDtTm.Top += delta;
                }
                Invalidate();
                Update();
            }
        }
        #endregion
    }
}
